package cn.demoncat.util.mongo.util;

import java.util.Map;

import org.springframework.data.geo.Box;
import org.springframework.data.geo.Circle;
import org.springframework.data.geo.Point;
import org.springframework.data.mongodb.core.query.Criteria;

import cn.demoncat.util.lang.LocalDateUtil;
import cn.demoncat.util.lang.ParamEmptyUtil;
import cn.demoncat.util.mongo.constant.MongoConstant;

/**
 * MongoDB条件工具（获取条件参数Criteria）
 *
 * @author 延晓磊
 *
 * @since 2017年7月22日
 */
public class CriteriaUtil {

	/**
	 * 条件链 - [cri1 && cri2]
	 * 
	 * @param cri	$and条件参数
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria add(Criteria... cri) {
		// { $and: [ { price: { $ne: 1.99 } }, { price: { $exists: true } } ] }
		return new Criteria().andOperator(cri);
	}
	
	/**
	 * 条件链 - [other1 && other2]
	 * 
	 * @param cri		条件参数
	 * @param other		$and条件参数
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria add(Criteria cri, Criteria... other) {
		// { $and: [ { price: { $ne: 1.99 } }, { price: { $exists: true } } ] }
		return cri.andOperator(other);
	}
	
	/**
	 * 条件链 - [cri1 || cri2]
	 * 
	 * @param cri		条件参数
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria or(Criteria... cri) {
		// { $or: [ { quantity: { $lt: 20 } }, { price: 10 } ] }
		return new Criteria().orOperator(cri);
	}
	
	/**
	 * 条件链 - [other1 || other2]
	 * 
	 * @param cri		条件参数
	 * @param other		$or条件参数
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria or(Criteria cri, Criteria... other) {
		// { $or: [ { quantity: { $lt: 20 } }, { price: 10 } ] }
		return cri.orOperator(other);
	}
	
	/**
	 * 条件链 - [!cri1 && !cri2]
	 * 
	 * @param cri		$nor条件参数
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria nor(Criteria... cri) {
		// { $nor: [ { price: 1.99 }, { sale: true } ]  }
		return new Criteria().norOperator(cri);
	}
	
	/**
	 * 条件链 - [!other1 && !other2]
	 * 
	 * @param cri		条件参数
	 * @param other		$nor条件参数
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria nor(Criteria cri, Criteria... other) {
		// { $nor: [ { price: 1.99 }, { sale: true } ]  }
		return cri.norOperator(other);
	}
	
	/**
	 * 文档 - 包含域
	 * 
	 * @param field		域名
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria exists(String field) {
		//  { field: { $exists: <boolean> } }
		return Criteria.where(field).exists(true);
	}
	
	/**
	 * 文档 - 包含域
	 * 
	 * @param cri		条件参数
	 * @param field		域名
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria exists(Criteria cri, String field) {
		//  { field: { $exists: <boolean> } }
		return cri.and(field).exists(true);
	}
	
	/**
	 * 文档 - 不包含域
	 * 
	 * @param field		域名
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria notExists(String field) {
		//  { field: { $exists: <boolean> } }
		return Criteria.where(field).exists(false);
	}
	
	/**
	 * 文档 - 不包含域
	 * 
	 * @param cri		条件参数
	 * @param field		域名
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria notExists(Criteria cri, String field) {
		//  { field: { $exists: <boolean> } }
		return cri.and(field).exists(false);
	}
	
	/**
	 * 数组 - 包含元素
	 * 
	 * @param field		域名：数组类型
	 * @param value		数组中包含的元素
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria all(String field, Object... value) {
		// { field: { $all: [ <value1> , <value2> ... ] } }
		return Criteria.where(field).all(value);
	}
	
	/**
	 * 数组 - 包含元素
	 * 
	 * @param cri		条件参数
	 * @param field		域名：数组类型
	 * @param value		数组中包含的元素
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria all(Criteria cri, String field, Object...value) {
		// { field: { $all: [ <value1> , <value2> ... ] } }
		return cri.and(field).all(value);
	}
	
	/**
	 * 域 - 大于
	 * 
	 * @param field		域名
	 * @param value		比较值
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria gt(String field, Object value) {
		// {field: {$gt: value} }
		return Criteria.where(field).gt(value);
	}
	
	/**
	 * 域 - 大于
	 * 
	 * @param cri		条件参数
	 * @param field		域名
	 * @param value		比较值
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria gt(Criteria cri, String field, Object value) {
		// {field: {$gt: value} }
		return cri.and(field).gt(value);
	}
	
	/**
	 * 域 - 大于等于
	 * 
	 * @param field		域名
	 * @param value		比较值
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria gte(String field, Object value) {
		// {field: {$gte: value} }
		return Criteria.where(field).gte(value);
	}
	
	/**
	 * 域 - 大于等于
	 * 
	 * @param cri		条件参数
	 * @param field		域名
	 * @param value		比较值
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria gte(Criteria cri, String field, Object value) {
		// {field: {$gte: value} }
		return cri.and(field).gte(value);
	}
	
	/**
	 * 域 - 等于
	 * 
	 * @param field		域名
	 * @param value		比较值
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria is(String field, Object value) {
		// {field: value}
		return Criteria.where(field).is(value);
	}
	
	/**
	 * 域 - 等于
	 * 
	 * @param cri		条件参数
	 * @param field		域名
	 * @param value		比较值
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria is(Criteria cri, String field, Object value) {
		// {field: value}
		return cri.and(field).is(value);
	}
	
	/**
	 * 域 - 等于
	 * 
	 * @param kvs		域值对
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria is(Map<String, Object> kvs) {
		Criteria cri = new Criteria();
		for (Map.Entry<String, Object> kv : kvs.entrySet()) {
			if (ParamEmptyUtil.isNotEmpty(kv.getValue())) {
				cri = cri.and(kv.getKey()).is(kv.getValue());
			}
		}
		return cri;
	}
	
	/**
	 * 域 - 等于
	 * 
	 * @param cri		条件参数
	 * @param kvs		域值对
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria is(Criteria cri, Map<String, Object> kvs) {
		for (Map.Entry<String, Object> kv : kvs.entrySet()) {
			if (ParamEmptyUtil.isNotEmpty(kv.getValue())) {
				cri = cri.and(kv.getKey()).is(kv.getValue());
			}
		}
		return cri;
	}
	
	/**
	 * 域 - 等于
	 * 
	 * @param pojo	查询对象（匹配非空属性）
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria by(Object pojo) {
		return Criteria.byExample(pojo);
	}
	
	/**
	 * 域 - 不等于
	 * 
	 * @param field		域名
	 * @param value		比较值
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria ne(String field, Object value) {
		// {field: {$ne: value} }
		return Criteria.where(field).ne(value);
	}
	
	/**
	 * 域 - 不等于
	 * 
	 * @param cri		条件参数
	 * @param field		域名
	 * @param value		比较值
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria ne(Criteria cri, String field, Object value) {
		// {field: {$ne: value} }
		return cri.and(field).ne(value);
	}
	
	/**
	 * 域 - 小于
	 * 
	 * @param field		域名
	 * @param value		比较值
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria lt(String field, Object value) {
		// {field: {$lt: value} }
		return Criteria.where(field).lt(value);
	}
	
	/**
	 * 域 - 小于
	 * 
	 * @param cri		条件参数
	 * @param field		域名
	 * @param value		比较值
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria lt(Criteria cri, String field, Object value) {
		// {field: {$lt: value} }
		return cri.and(field).lt(value);
	}
	
	/**
	 * 域 - 小于等于
	 * 
	 * @param field		域名
	 * @param value		比较值
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria lte(String field, Object value) {
		// {field: {$lte: value} }
		return Criteria.where(field).lte(value);
	}
	
	/**
	 * 域 - 小于等于
	 * 
	 * @param cri		条件参数
	 * @param field		域名
	 * @param value		比较值
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria lte(Criteria cri, String field, Object value) {
		// {field: {$lte: value} }
		return cri.and(field).lte(value);
	}
	
	/**
	 * 字段 - 区间
	 * 
	 * @param field	字段名：数值，日期，字符串（性能低）
	 * @param min	最小值（包含）
	 * @param max	最大值
	 * 
	 * @return min和max都为空时返回new Criteria 
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020-9-3
	 */
	public static Criteria between(String field, Object min, Object max) {
		if (min == null && max == null) {
			return new Criteria();
		}
		if (min == null) {
			return lt(field, max);
		}
		if (max == null) {
			return gte(field, min);
		}
		return new Criteria(field).gte(min).lt(max);
	}
	
	/**
	 * 字段 - 区间
	 * 
	 * @param cri		条件参数
	 * @param field		字段名：数值，日期，字符串（性能低）
	 * @param min		最小值（包含）
	 * @param max		最大值
	 * 
	 * @return min和max都为空时返回cri
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020-9-3
	 */
	public static Criteria between(Criteria cri, String field, Object min, Object max) {
		if (min == null && max == null) {
			return cri;
		}
		if (min == null) {
			return lt(cri, field, max);
		}
		if (max == null) {
			return gte(cri, field, min);
		}
		return cri.and(field).gte(min).lt(max);
	}
	
	/**
	 * 时间区间
	 * 
	 * @param field
	 * @param startTime
	 * @param endTime
	 * @return 时间都为空则返回new Criteria
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年5月1日
	 */
	public static Criteria timeRange(String field, String startTime, String endTime) {
		return between(field, LocalDateUtil.toLocalDateTime(startTime), LocalDateUtil.toLocalDateTime(endTime));
	}
	
	/**
	 * 时间区间
	 * 
	 * @param cri	条件参数
	 * @param field
	 * @param startTime
	 * @param endTime
	 * @return 时间都为空则返回cri
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年5月1日
	 */
	public static Criteria timeRange(Criteria cri, String field, String startTime, String endTime) {
		return between(cri, field, LocalDateUtil.toLocalDateTime(startTime), LocalDateUtil.toLocalDateTime(endTime));
	}
	
	/**
	 * 域 - 在列表中
	 * 
	 * @param field		域名
	 * @param value		比较值
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria in(String field, Object... value) {
		// {field: { $in: [ 5, 15 ] }}
		return Criteria.where(field).in(value);
	}
	
	/**
	 * 域 - 在列表中
	 * 
	 * @param cri		条件参数
	 * @param field		域名
	 * @param value		比较值
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria in(Criteria cri, String field, Object... value) {
		// {field: { $in: [ 5, 15 ] }}
		return cri.and(field).in(value);
	}
	
	/**
	 * 域 - 不在列表中
	 * 
	 * @param field		域名
	 * @param value		比较值
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria nin(String field, Object... value) {
		// {field: { $nin: [ 5, 15 ] }}
		return Criteria.where(field).nin(value);
	}
	
	/**
	 * 域 - 不在列表中
	 * 
	 * @param cri		条件参数
	 * @param field		域名
	 * @param value		比较值
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria nin(Criteria cri, String field, Object... value) {
		// {field: { $nin: [ 5, 15 ] }}
		return cri.and(field).nin(value);
	}
	
	/**
	 * 域 - 取模
	 * 
	 * @param field		域名
	 * @param mod		模数
	 * @param remainder	余
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria mod(String field, Number mod, Number remainder) {
		// {field: { $mod: [ 4, 0 ] }}
		return Criteria.where(field).mod(mod, remainder);
	}
	
	/**
	 * 域 - 取模
	 * 
	 * @param cri		条件参数
	 * @param field		域名
	 * @param mod		模数
	 * @param remainder	余
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria mod(Criteria cri, String field, Number mod, Number remainder) {
		// {field: { $mod: [ 4, 0 ] }}
		return cri.and(field).mod(mod, remainder);
	}
	
	/**
	 * 域 - 取模余0
	 * 
	 * @param field		域名
	 * @param mod		模数
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria mod(String field, Number mod) {
		// {field: { $mod: [ 4, 0 ] }}
		return Criteria.where(field).mod(mod, 0);
	}
	
	/**
	 * 域 - 取模余0
	 * 
	 * @param cri		条件参数
	 * @param field		域名
	 * @param mod		模数
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria mod(Criteria cri, String field, Number mod) {
		// {field: { $mod: [ 4, 0 ] }}
		return cri.and(field).mod(mod, 0);
	}
	
	/**
	 * 域 - 正则
	 * 
	 * @param field		域名
	 * @param value		正则：/^a.*$/ 或 ^a.*$
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria regex(String field, String value) {
		// {field: { $regex: /789$/ } }
		return Criteria.where(field).regex(value);
	}
	
	/**
	 * 域 - 正则
	 * 
	 * @param cri		条件参数
	 * @param field		域名
	 * @param value		正则：/^a.*$/ 或 ^a.*$
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria regex(Criteria cri, String field, String value) {
		// {field: { $regex: /789$/ } }
		return cri.and(field).regex(value);
	}
	
	/**
	 * 域 - 正则（不区分大小写）
	 * 
	 * @param field		域名
	 * @param value		正则：/^a.*$/ 或 ^a.*$
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria regexIgnoreCase(String field, String value) {
		// {field: { $regex: /^ABC/i } }
		return Criteria.where(field).regex(value, "i");
	}
	
	/**
	 * 域 - 正则（不区分大小写）
	 * 
	 * @param cri		条件参数
	 * @param field		域名
	 * @param value		正则：/^a.*$/ 或 ^a.*$
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria regexIgnoreCase(Criteria cri, String field, String value) {
		// {field: { $regex: /^ABC/i } }
		return cri.and(field).regex(value, "i");
	}
	
	/**
	 * 域 - 正则取反
	 * 
	 * @param field		域名
	 * @param value		正则：/^a.*$/ 或 ^a.*$
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria notRegex(String field, String value) {
		// {field: { $not: { $regex: /^p.*/ } } }
		return Criteria.where(field).not().regex(value);
	}
	
	/**
	 * 域 - 正则取反
	 * 
	 * @param cri		条件参数
	 * @param field		域名
	 * @param value		正则：/^a.*$/ 或 ^a.*$
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria notRegex(Criteria cri, String field, String value) {
		// {field: { $not: { $regex: /^p.*/ } } }
		return cri.and(field).not().regex(value);
	}
	
	/**
	 * 域 - 正则（不区分大小写）取反
	 * 
	 * @param field		域名
	 * @param value		正则：/^a.*$/ 或 ^a.*$
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria notRegexIgnoreCase(String field, String value) {
		// {field: { $not: { $regex: /^p.*/i } } }
		return Criteria.where(field).not().regex(value, "i");
	}
	
	/**
	 * 域 - 正则（不区分大小写）取反
	 * 
	 * @param cri		条件参数
	 * @param field		域名
	 * @param value		正则：/^a.*$/ 或 ^a.*$
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria notRegexIgnoreCase(Criteria cri, String field, String value) {
		// {field: { $not: { $regex: /^p.*/i } } }
		return cri.and(field).not().regex(value, "i");
	}
	
	/**
	 * 模糊匹配：like '%xxx%'
	 * 
	 * @param field		属性
	 * @param value		值
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年5月15日
	 */
	public static Criteria like(String field, String value) {
		return regex(field, value);
	}
	
	/**
	 * 模糊匹配：like '%xxx%'
	 * 
	 * @param cri		条件参数
	 * @param field		属性
	 * @param value		值
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年5月15日
	 */
	public static Criteria like(Criteria cri, String field, String value) {
		return regex(cri, field, value);
	}

	/**
	 * 模糊匹配：like 'xxx%'
	 * 
	 * @param field		属性
	 * @param value		值
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年5月15日
	 */
	public static Criteria likeLeft(String field, String value) {
		return regex(field, "^" + value);
	}
	
	/**
	 * 模糊匹配：like 'xxx%'
	 * 
	 * @param cri		条件参数
	 * @param field		属性
	 * @param value		值
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年5月15日
	 */
	public static Criteria likeLeft(Criteria cri, String field, String value) {
		return regex(cri, field, "^" + value);
	}
	
	/**
	 * 模糊匹配：like '%xxx'
	 * 
	 * @param field		属性
	 * @param value		值
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年5月15日
	 */
	public static Criteria likeRight(String field, String value) {
		return regex(field, value + "$");
	}
	
	/**
	 * 模糊匹配：like '%xxx'
	 * 
	 * @param cri		条件参数
	 * @param field		属性
	 * @param value		值
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年5月15日
	 */
	public static Criteria likeRight(Criteria cri, String field, String value) {
		return regex(cri, field, value + "$");
	}
	
	/**
	 * ID
	 * 
	 * @param value		值
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria id(Object value) {
		return is(MongoConstant.ID_FIELD, value);
	}
	
	/**
	 * ID
	 * 
	 * @param cri		条件参数
	 * @param value		值
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria id(Criteria cri, Object value) {
		return is(cri, MongoConstant.ID_FIELD, value);
	}
	
	/**
	 * 地理空间 - 方格区域
	 * 
	 * @param field			位置字段：double[x,y]
	 * @param lowerLeftX	左下角
	 * @param lowerLeftY
	 * @param upperRightX	右上角
	 * @param upperRightY
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria withinBox(String field, double lowerLeftX, double lowerLeftY, double upperRightX, double upperRightY) {
		return Criteria.where(field).within(new Box(new Point(lowerLeftX, lowerLeftY), new Point(upperRightX, upperRightY)));
	}
	
	/**
	 * 地理空间 - 方格区域
	 * 
	 * @param cri			条件参数
	 * @param field			位置字段：double[x,y]
	 * @param lowerLeftX	左下角
	 * @param lowerLeftY
	 * @param upperRightX	右上角
	 * @param upperRightY
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria withinBox(Criteria cri, String field, double lowerLeftX, double lowerLeftY, double upperRightX, double upperRightY) {
		return cri.and(field).within(new Box(new Point(lowerLeftX, lowerLeftY), new Point(upperRightX, upperRightY)));
	}
	
	/**
	 * 地理空间 - 圆形区域
	 * 
	 * @param field		位置字段：double[x,y]
	 * @param centerX	圆心
	 * @param centerY
	 * @param radius	半径
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria withinCircle(String field, double centerX, double centerY, double radius) {
		return Criteria.where(field).within(new Circle(centerX, centerY, radius));
	}
	
	/**
	 * 地理空间 - 圆形区域
	 * 
	 * @param cri		条件参数
	 * @param field		位置字段：double[x,y]
	 * @param centerX	圆心
	 * @param centerY
	 * @param radius	半径
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria withinCircle(Criteria cri, String field, double centerX, double centerY, double radius) {
		return cri.and(field).within(new Circle(centerX, centerY, radius));
	}
	
	/**
	 * 地理空间 - 圆形区域（球面）
	 * 
	 * @param field		位置字段：double[x,y]
	 * @param centerX	圆心
	 * @param centerY
	 * @param radius	半径
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria withinCircleSphere(String field, double centerX, double centerY, double radius) {
		return Criteria.where(field).withinSphere(new Circle(centerX, centerY, radius));
	}
	
	/**
	 * 地理空间 - 圆形区域（球面）
	 * 
	 * @param cri		条件参数
	 * @param field		位置字段：double[x,y]
	 * @param centerX	圆心
	 * @param centerY
	 * @param radius	半径
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria withinCircleSphere(Criteria cri, String field, double centerX, double centerY, double radius) {
		return cri.and(field).withinSphere(new Circle(centerX, centerY, radius));
	}
	
	/**
	 * 地理空间 - 附近
	 * 
	 * @param field		位置字段：double[x,y]
	 * @param x			基准位置
	 * @param y
	 * @param distance	最远距离
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria near(String field, double x, double y, double distance) {
		return Criteria.where(field).near(new Point(x, y)).maxDistance(distance);
	}
	
	/**
	 * 地理空间 - 附近
	 * 
	 * @param cri		条件参数
	 * @param field		位置字段：double[x,y]
	 * @param x			基准位置
	 * @param y
	 * @param distance	最远距离
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria near(Criteria cri, String field, double x, double y, double distance) {
		return cri.and(field).near(new Point(x, y)).maxDistance(distance);
	}
	
	/**
	 * 地理空间 - 附近
	 * 
	 * @param field		位置字段：double[x,y]
	 * @param x			基准位置
	 * @param y
	 * @param min		最近距离
	 * @param max		最远距离
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria near(String field, double x, double y, double min, double max) {
		return Criteria.where(field).near(new Point(x, y)).minDistance(min).maxDistance(max);
	}
	
	/**
	 * 地理空间 - 附近
	 * 
	 * @param cri		条件参数
	 * @param field		位置字段：double[x,y]
	 * @param x			基准位置
	 * @param y
	 * @param min		最近距离
	 * @param max		最远距离
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria near(Criteria cri, String field, double x, double y, double min, double max) {
		return cri.and(field).near(new Point(x, y)).minDistance(min).maxDistance(max);
	}
	
	/**
	 * 地理空间 - 附近（球面）
	 * 
	 * @param field		位置字段：double[x,y]
	 * @param x			基准位置
	 * @param y
	 * @param distance	最远距离
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria nearSphere(String field, double x, double y, double distance) {
		return Criteria.where(field).nearSphere(new Point(x, y)).maxDistance(distance);
	}
	
	/**
	 * 地理空间 - 附近（球面）
	 * 
	 * @param cri		条件参数
	 * @param field		位置字段：double[x,y]
	 * @param x			基准位置
	 * @param y
	 * @param distance	最远距离
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria nearSphere(Criteria cri, String field, double x, double y, double distance) {
		return cri.and(field).nearSphere(new Point(x, y)).maxDistance(distance);
	}
	
	/**
	 * 地理空间 - 附近（球面）
	 * 
	 * @param field		位置字段：double[x,y]
	 * @param x			基准位置
	 * @param y
	 * @param min		最近距离
	 * @param max		最远距离
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria nearSphere(String field, double x, double y, double min, double max) {
		return Criteria.where(field).nearSphere(new Point(x, y)).minDistance(min).maxDistance(max);
	}
	
	/**
	 * 地理空间 - 附近（球面）
	 * 
	 * @param cri		条件参数
	 * @param field		位置字段：double[x,y]
	 * @param x			基准位置
	 * @param y
	 * @param min		最近距离
	 * @param max		最远距离
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年8月28日
	 */
	public static Criteria nearSphere(Criteria cri, String field, double x, double y, double min, double max) {
		return cri.and(field).nearSphere(new Point(x, y)).minDistance(min).maxDistance(max);
	}
	
}
